#ifndef __WIDGET_H__
#define __WIDGET_H__

#include <string>

#include <Metgine/Config.h>
#include <Metgine/Core/Vector2.h>
#include <Metgine/Graphics/Sprite.h>
#include <SFML/Window/Input.hpp>


using namespace Metgine::Core;
using namespace Metgine::Graphics;

namespace Metgine
{
namespace UI
{

class UIManager;


namespace Group
{

enum Group
{

    All             = -1,
    None            = 0,
    System          = 1,        // Never cleared (console)
    Game            = 2,        // Anything used in the main game
    Other           = 4,        // Temporary store for stuff like the loading graphics that will be cleared often

};

};

// forward declaration for typedefs;
class Widget;

typedef void (*MouseClickCallback)(Widget*, sf::Mouse::Button);
typedef void (*MouseEnterCallback)(Widget*);
typedef void (*MouseLeaveCallback)(Widget*);

class METGINE_API Widget
{
public:

    // Constructors
    Widget(const std::string& _name, Group::Group _group = Group::None, bool _visible = true, bool _enabled = true);
    Widget(const std::string& _name, Group::Group _group, const Vector2i& position, const Vector2i& extents);

    // Sets the owner of the widget
    virtual void SetOwner(UIManager* _owner);

    // Gets the name of the widget
    virtual const std::string& GetName() const;

    // Sets the position of the widget
    virtual void SetPosition(const Vector2i& position);

    // Gets the position of the widget
    virtual const Vector2i& GetPosition() const;

    // Sets the size of the widget
    virtual void SetSize(const Vector2i& size);

    virtual void SetSprite(const Sprite&);
    virtual const int GetWidth() const;
    virtual const int GetHeight() const;

    // Returns true if the widget contains a point
    virtual bool Contains(const sf::Vector2i& point);

    // Sets the callback for Mouse click events
    void SetOnClick(MouseClickCallback);

    // Sets the call back for Mouse enter events
    void SetOnMouseEnter(MouseEnterCallback);

    // Sets the callback for Mouse leave events
    void SetOnMouseLeave(MouseLeaveCallback);

    // Updates the widget
    virtual void Update(float elapsedTime);

    // Renders the widget
    virtual void Render();

    // Returns true if the widget is visible
    virtual bool IsVisible() const;

    // Sets the visibility of the widget
    virtual void SetVisible(bool state);

    // Returns true if the widget is enabled
    virtual bool IsEnabled() const;

    // Sets if the widget is enabled
    virtual void SetEnabled(bool state);

    // Sets the group the widgets belongs to
    virtual void SetGroup(Group::Group newGroup);

    // Gets the group the widgets belongs to
    virtual unsigned int GetGroup() const;

    // Handles a key press
    virtual bool KeyDown(sf::Key::Code key, bool shift, bool control, bool alt);

    // Handles a key release
    virtual bool KeyUp(sf::Key::Code key, bool shift, bool control, bool alt);


protected:
    virtual void OnClick();
    virtual void OnMouseEnter();
    virtual void OnMouseLeave();

    UIManager*      m_owner;            // Pointer to owning UIManager instance
    std::string     m_name;             // Name of the widget

    Sprite          m_sprite;
    Vector2i        m_position;
    Vector2i        m_size;
    Group::Group  m_group;              // Group to which this widget belongs
    bool            m_visible;          // Is the widget visible
    bool            m_enabled;          // Is the widget enabled (does it respond to user input?)

    MouseClickCallback         m_mouseClickCallback;
    MouseEnterCallback         m_mouseEnterCallback;
    MouseLeaveCallback         m_mouseLeaveCallback;
};

}; // UI
}; // Metgine


#endif // WIDGET_H
